//@author wtfumlomglol
package amm.Graphic;

import java.io.*;
import java.util.*;

//keresztezodest leiro osztaly
public class XRoads extends Road {

    //ervenyes kimeno utakat jelzo tomb - skeleton nem hasznalja
    private boolean[] roadLegal = new boolean[4];
    //nem feltetlenul tartalmaz lampakat
    private LightController lightControl;
    //a bankrablo leallitasahoz kell
    private Logger logger;

    //lampa nelkuli keresztezodes
    public XRoads(int index) {
        for (int i = 0; i < 4; i++) {
            roadLegal[i] = false;
        }
        this.name = "XRoads[" + index + "]";
    }

    //lampas keresztezodes
    public XRoads(Compass c, int index, Logger logger) {
        this.name = "XRoads[" + index + "]";
        lightControl = new LightController(c, this);
        this.logger = logger;
    }

    @Override
    public void setNeighbour(Field f, Compass c, Direction d) {
        Neighbour n = new Neighbour(f);
        n.setCompass(c);
        n.setDirection(d);
        neighbours.add(n);
    }

    @Override
    public Place getPlace() {
        return Place.XROADS;
    }

    //ellenorizzuk, hogy foglalt-e
    @Override
    public boolean checkOccupy() {
        //mivel a bankrablo sosem hiv ilyen metodust,
        //ezzel a flaggel lehet azonositani es megallitani
        return !isFree;
    }

    //egy jarmu elfogadasanak modja azonos az uteval
    @Override
    public void acceptVehicle(Vehicle v) {
        if (!isFree) {
            occupiedBy.visit((Criminal) v);
        }
        occupiedBy = v;
        isFree = false;
        occupiedBy.forceStop();
    }

    public LightController getLC() {
        return lightControl;
    }

    @Override
    public Neighbour getNeighbour(int i) {
        if (i >= 0 && i < 4) {
            return neighbours.get(i);
        } else {
            return null;
        }
    }

    //ha egy jarmu elhagyja
    @Override
    public void leave(boolean forward, Compass c) {
        Field next = null;
        //ha civil
        if (c == null) {
            Citizen cz = (Citizen) occupiedBy;
            CitizenType ct = cz.getType();
            switch (ct) {
                case TRABANT: {
                    ArrayList<Neighbour> leadout = new ArrayList<Neighbour>();
                    for (Neighbour n : neighbours) {
                        if (n.getDirection() == Direction.FORWARD) {
                            leadout.add(n);
                        }
                    }
                    for (Neighbour n : leadout) {
                        if (n.getCompass() == Compass.EAST) {
                            next = n.getNextRoute(occupiedBy);
                            break;
                        }
                        
                    }
                    if (next == null) {
                        for (Neighbour n : leadout) {
                            if (n.getCompass() == Compass.SOUTH) {
                                next = n.getNextRoute(occupiedBy);
                                break;
                            }
                            
                        }
                    }
                    if (next == null) {
                        for (Neighbour n : leadout) {
                            if (n.getCompass() == Compass.WEST) {
                                next = n.getNextRoute(occupiedBy);
                                break;
                            }
                        }
                    }
                    if (next == null) {
                        for (Neighbour n : leadout) {
                            if (n.getCompass() == Compass.NORTH) {
                                next = n.getNextRoute(occupiedBy);
                                break;
                            }
                        }
                    }
                    break;
                }
                case VOLKSWAGEN: {
                    ArrayList<Neighbour> leadout = new ArrayList<Neighbour>();
                    for (Neighbour n : neighbours) {
                        if (n.getDirection() == Direction.FORWARD) {
                            leadout.add(n);
                        }
                    }
                    for (Neighbour n : leadout) {
                        if (n.getCompass() == Compass.NORTH) {
                            next = n.getNextRoute(occupiedBy);
                            break;
                        }
                    }
                    if (next == null) {
                        for (Neighbour n : leadout) {
                            if (n.getCompass() == Compass.EAST) {
                                next = n.getNextRoute(occupiedBy);
                                break;
                            }
                        }
                    }
                    if (next == null) {
                        for (Neighbour n : leadout) {
                            if (n.getCompass() == Compass.SOUTH) {
                                next = n.getNextRoute(occupiedBy);
                                break;
                            }
                        }
                    }
                    if (next == null) {
                        for (Neighbour n : leadout) {
                            if (n.getCompass() == Compass.WEST) {
                                next = n.getNextRoute(occupiedBy);
                                break;
                            }
                        }
                    }
                    break;
                }
                case LAMBORGHINI: {
                    ArrayList<Neighbour> leadout = new ArrayList<Neighbour>();
                    for (Neighbour n : neighbours) {
                        if (n.getDirection() == Direction.FORWARD) {
                            leadout.add(n);
                        }
                    }
                    for (Neighbour n : leadout) {
                        if (n.getCompass() == Compass.WEST) {
                            next = n.getNextRoute(occupiedBy);
                            break;
                        }
                    }
                    if (next == null) {
                        for (Neighbour n : leadout) {
                            if (n.getCompass() == Compass.SOUTH) {
                                next = n.getNextRoute(occupiedBy);
                                break;
                            }
                        }
                    }
                    if (next == null) {
                        for (Neighbour n : leadout) {
                            if (n.getCompass() == Compass.NORTH) {
                                next = n.getNextRoute(occupiedBy);
                                break;
                            }
                        }
                    }
                    if (next == null) {
                        for (Neighbour n : leadout) {
                            if (n.getCompass() == Compass.EAST) {
                                next = n.getNextRoute(occupiedBy);
                                break;
                            }
                        }
                    }
                    break;
                }
            }

        } //ha bankrablo, az altala megadott iranyba kuldi tovabb az igenyt
        else {
            Neighbour n;
            Criminal cv = (Criminal) occupiedBy;
            for (int i = 0; i < 4; i++) {
                n = neighbours.get(i);
                if (n.getCompass() == c) {
                    next = n.getNextRouteC(occupiedBy);
                    //a bankrablo haladasi iranyat a szomszedera allitja
                    cv.setDirection(n.getDirection());
                    break;
                }

            }
        }
        //ha van ervenyes szomszed mezo
        if (next != null) {
            //elmenti az aktualis jarmuve referenciajat, hogy a clear() hivas utan is hasznalhassa azt
            Vehicle veh = occupiedBy;
            occupiedBy.moveTo(next);
        } //ha nincs ervenyes mezo, szol a jarmunek, hogy maradjon.
        else {
            occupiedBy.moveTo(this);
        }
    }

    //ha egy rendor vizsgalni akar, ertesiti az osszes szomszedjat
    @Override
    public void bustCriminal() {
        for (Neighbour n : neighbours) {
            n.investigate();
        }
    }

    //lekérdezi, hogy van-e adott irányba szomszédja
    public boolean hasNeighbour(Compass c) {
        for (Neighbour n : neighbours) {
            if (n.getCompass() == c) {
                return true;
            }
        }
        return false;
    }

    //térképhez szolgáltat rajzjelet
    @Override
    public String getMark() {
        //ha foglalt, az autó jelét használja
        if (occupiedBy != null) {
            return occupiedBy.getMark();
        }
        //ha van rajta nyul
        if (powerUp == PowerUp.EASTERBUNNY) {
            return "Y";
        }
        //ha nem lámpás
        if (lightControl == null) {
            return "+";
        }
        //ha lámpás
        switch (lightControl.getActive()) {
            case 0:
                return "E";
            case 1:
                return "N";
            case 2:
                return "W";
            case 3:
                return "S";
            default:
                return "+";
        }
    }

    //visszaadja a naplózó objektum referenciáját
    public Logger getLogger() {
        return logger;
    }
}

